package io.itit.ecp.admin.provide.action.controller.miniprogram;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import icu.mhb.mybatisplus.plugln.extend.Joins;
import io.itit.ecp.admin.common.enums.IMeterDeviceEnums;
import io.itit.ecp.admin.common.enums.MeterDeviceStaticsTypeEnums;
import io.itit.ecp.admin.provide.action.resp.miniprogram.PersonalizedEnergyChargingStationResp;
import io.itit.ecp.admin.provide.action.resp.miniprogram.PersonalizedEnergyPowerResp;
import io.itit.ecp.admin.provide.action.resp.miniprogram.PersonalizedEnergyStorageResp;
import io.itit.ecp.admin.server.entity.*;
import io.itit.ecp.admin.server.service.*;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 个性化用能报告
 */
@Api(tags = {"个性化用能报告"})
@RestController
@RequiredArgsConstructor
@RequestMapping("/mini/personalizedEnergyReport")
public class MiniPersonalizedEnergyReportController {

    private static final String[] DEFAULT_REMARKS = {
            "绿色能源显神威，节能减排谱新篇。",
            "清洁能源扬美名，节能高效传佳话。",
            "绿色能源兴大业，节能减排护家园。",
            "能源转型正当时，节能减排显担当。",
            "绿色能源泽四方，节能减排利千秋。",
            "清洁能源照前路，节能降耗谱华章。",
            "绿色能源显身手，节能减排筑绿洲。",
            "能源革新促发展，节能减排保安康。",
            "绿色能源映朝阳，节能减排谱辉煌。",
            "清洁能源领风骚，节能高效写新篇。",
            "绿色能源照人心，节能减排守蓝天。",
            "能源转型创未来，节能减排守绿意。",
            "绿色能源泽众生，节能减排护地球。",
            "清洁能源扬正气，节能降耗赢民心。",
            "绿色能源显威力，节能减排保家园。",
    };


    @Resource
    private IEnergyConsumptionTypeService energyConsumptionTypeService;

    @Resource
    private IEnergyDataService energyDataService;

    @Resource
    private ISceneRoomService sceneRoomService;

    @Resource
    private IMeterDeviceService meterDeviceService;

    @Resource
    private IProductTypeService productTypeService;

    @Resource
    private IPhysicalModelService physicalModelService;

    /**
     * 能耗类型统计
     */
    @ApiOperation("能耗类型统计")
    @GetMapping("energyConsumptionTypeStatics")
    public ResultResp<Map<String, Object>> energyConsumptionTypeStatics(@RequestParam(required = false) String sceneProjectId,
                                                                        @RequestParam(required = false) String sceneCompanyId,
                                                                        @RequestParam(required = false) String startTime,
                                                                        @RequestParam(required = false) String endTime) {
        List<EnergyConsumptionTypeEntity> energyConsumptionTypeEntities = energyConsumptionTypeService.lambdaQuery()
                .eq(EnergyConsumptionTypeEntity::getStatus, "1")
                .list();

        List<Map<String, Object>> dataList = new ArrayList<>();
        List<EnergyDataEntity> list = Collections.emptyList();
        if (!energyConsumptionTypeEntities.isEmpty()) {
            Set<String> energyTypeIds = energyConsumptionTypeEntities.stream()
                    .map(EnergyConsumptionTypeEntity::getId).collect(Collectors.toSet());

            LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
            LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();
            list = Joins.of(EnergyDataEntity.class)
                    .selectAs(builder -> {
                        builder.add("energy_type_id", "energyTypeId", false);
                        builder.add("SUM(standard_coal)", "standardCoal", false);
                        builder.add("SUM(meter_Value)", "meterValue", false);
                    })
                    .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                    .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                    .in(EnergyDataEntity::getEnergyTypeId, energyTypeIds)
                    .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                    .le(EnergyDataEntity::getSolidifyDate, end)
                    .groupBy(EnergyDataEntity::getEnergyTypeId).joinList(EnergyDataEntity.class);


        }
        for (EnergyConsumptionTypeEntity item : energyConsumptionTypeEntities) {
            Map<String, Object> m = new HashMap<>(3);
            EnergyDataEntity energyDataEntity = list.stream().filter(energyData -> StringUtils.equals(energyData.getEnergyTypeId(), item.getId()))
                    .findFirst()
                    .orElse(null);
            m.put("energyTypeId", item.getId());
            m.put("energyTypeName", item.getEnergyName());
            m.put("energyUnit", item.getEnergyUnit());
            m.put("standardCoal", Objects.isNull(energyDataEntity) || Objects.isNull(energyDataEntity.getStandardCoal()) ? BigDecimal.ZERO : energyDataEntity.getStandardCoal().setScale(2, RoundingMode.HALF_DOWN));
            m.put("meterValue", Objects.isNull(energyDataEntity) || Objects.isNull(energyDataEntity.getMeterValue()) ? BigDecimal.ZERO : energyDataEntity.getMeterValue().setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(m);
        }
        Map<String, Object> result = new HashMap<>(2);
        result.put("remark", DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        result.put("dataList", dataList);
        return ResultResp.success(result);
    }

    /**
     * 时间用电分析
     */
    @ApiOperation("时间用电分析")
    @GetMapping("timeElectricStatics")
    public ResultResp<Map<String, Object>> timeElectricStatics(@RequestParam(required = false) String sceneProjectId,
                                                               @RequestParam(required = false) String sceneCompanyId,
                                                               @RequestParam(required = false) String startTime,
                                                               @RequestParam(required = false) String endTime) {
        String electricId = energyConsumptionTypeService.getElectricId();
        List<Map<String, Object>> dataList = new ArrayList<>();
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();
        Map<String, List<EnergyDataEntity>> list = Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> {
                    builder.add("solidify_date", "solidifyDate", false);
                    builder.add("SUM(meter_Value)", "meterValue", false);
                })
                .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                .eq(EnergyDataEntity::getEnergyTypeId, electricId)
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .groupBy(EnergyDataEntity::getSolidifyDate).joinList(EnergyDataEntity.class)
                .stream()
                .collect(Collectors.groupingBy(energyData -> DateUtil.format(energyData.getSolidifyDate(), "yyyy-MM-dd"),
                        LinkedHashMap::new, Collectors.toList()));
        for (Map.Entry<String, List<EnergyDataEntity>> entry : list.entrySet()) {
            String date = entry.getKey();
            BigDecimal value = entry.getValue().stream().map(EnergyDataEntity::getMeterValue).reduce(BigDecimal.ZERO, BigDecimal::add);
            Map<String, Object> map = new HashMap<>(2);
            map.put("date", date);
            map.put("value", value.setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
        }
        Map<String, Object> result = new HashMap<>(2);
        result.put("remark", DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        result.put("dataList", dataList);
        return ResultResp.success(result);
    }


    /**
     * 空间用电分析
     */
    @ApiOperation("空间用电分析(返回的dataList数组，长度为2的情况下，第一条是最大值统计，第二条为最小值统计)")
    @GetMapping("roomElectricStatics")
    public ResultResp<Map<String, Object>> roomElectricStatics(@RequestParam(required = false) String sceneProjectId,
                                                               @RequestParam(required = false) String sceneCompanyId,
                                                               @RequestParam(required = false) String startTime,
                                                               @RequestParam(required = false) String endTime) {
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();

        String electricId = energyConsumptionTypeService.getElectricId();
        Map<String, Object> result = new HashMap<>();
        result.put("remark", DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<SceneRoomEntity> roomEntityList;
        List<EnergyDataEntity> list = new ArrayList<>();
        if (StringUtils.isNotEmpty(sceneCompanyId)) {
            roomEntityList = sceneRoomService.list(new LambdaQueryWrapper<SceneRoomEntity>()
                    .eq(SceneRoomEntity::getSceneCompanyId, sceneCompanyId));
            // 公司要 关联2个以上的空间才为特殊空间
            if (roomEntityList.size() >= 2) {
                list = Joins.of(EnergyDataEntity.class)
                        .selectAs(builder -> {
                            builder.add("scene_room_id", "sceneRoomId", false);
                            builder.add("SUM(meter_Value)", "meterValue", false);
                        })
                        .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                        .eq(EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                        .eq(EnergyDataEntity::getEnergyTypeId, electricId)
                        .isNotNull(EnergyDataEntity::getSceneRoomId)
                        .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                        .le(EnergyDataEntity::getSolidifyDate, end)
                        .groupBy(EnergyDataEntity::getSceneRoomId).joinList(EnergyDataEntity.class);
            }

        } else {
            roomEntityList = sceneRoomService.list(new LambdaQueryWrapper<SceneRoomEntity>()
                    .eq(StringUtils.isNotEmpty(sceneProjectId), SceneRoomEntity::getSceneProjectId, sceneProjectId));
            list = Joins.of(EnergyDataEntity.class)
                    .selectAs(builder -> {
                        builder.add("scene_room_id", "sceneRoomId", false);
                        builder.add("SUM(meter_Value)", "meterValue", false);
                    })
                    .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                    .eq(EnergyDataEntity::getEnergyTypeId, electricId)
                    .isNotNull(EnergyDataEntity::getSceneRoomId)
                    .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                    .le(EnergyDataEntity::getSolidifyDate, end)
                    .groupBy(EnergyDataEntity::getSceneRoomId).joinList(EnergyDataEntity.class);
        }

        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.stream().max(Comparator.comparing(EnergyDataEntity::getMeterValue)).orElse(null);
            EnergyDataEntity minData = list.stream().min(Comparator.comparing(EnergyDataEntity::getMeterValue)).orElse(null);
            Map<String, Object> map = new HashMap<>(2);
            map.put("name", roomEntityList.stream().filter(item -> StringUtils.equals(item.getId(), maxData.getSceneRoomId())).findFirst().get().getRoomName());
            map.put("value", maxData.getMeterValue().setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
            map = new HashMap<>(2);
            map.put("name", roomEntityList.stream().filter(item -> StringUtils.equals(item.getId(), minData.getSceneRoomId())).findFirst().get().getRoomName());
            map.put("value", maxData.getMeterValue().setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
            result.put("dataList", dataList);
        }
        return ResultResp.success(result);
    }


    /**
     * 时间用水分析
     */
    @ApiOperation("时间用水分析")
    @GetMapping("timeWaterStatics")
    public ResultResp<Map<String, Object>> timeWaterStatics(@RequestParam(required = false) String sceneProjectId,
                                                            @RequestParam(required = false) String sceneCompanyId,
                                                            @RequestParam(required = false) String startTime,
                                                            @RequestParam(required = false) String endTime) {
        String electricId = energyConsumptionTypeService.getWaterId();
        List<Map<String, Object>> dataList = new ArrayList<>();
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();
        Map<String, List<EnergyDataEntity>> list = Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> {
                    builder.add("solidify_date", "solidifyDate", false);
                    builder.add("SUM(meter_Value)", "meterValue", false);
                })
                .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                .eq(EnergyDataEntity::getEnergyTypeId, electricId)
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .groupBy(EnergyDataEntity::getSolidifyDate).joinList(EnergyDataEntity.class)
                .stream()
                .collect(Collectors.groupingBy(energyData -> DateUtil.format(energyData.getSolidifyDate(), "yyyy-MM-dd"),
                        LinkedHashMap::new, Collectors.toList()));
        for (Map.Entry<String, List<EnergyDataEntity>> entry : list.entrySet()) {
            String date = entry.getKey();
            BigDecimal value = entry.getValue().stream().map(EnergyDataEntity::getMeterValue).reduce(BigDecimal.ZERO, BigDecimal::add);
            Map<String, Object> map = new HashMap<>(2);
            map.put("date", date);
            map.put("value", value.setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
        }
        Map<String, Object> result = new HashMap<>(2);
        result.put("remark", DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        result.put("dataList", dataList);
        return ResultResp.success(result);
    }


    /**
     * 空间用水分析
     */
    @ApiOperation("空间用水分析(返回的dataList数组，长度为2的情况下，第一条是最大值统计，第二条为最小值统计)")
    @GetMapping("roomWaterStatics")
    public ResultResp<Map<String, Object>> roomWaterStatics(@RequestParam(required = false) String sceneProjectId,
                                                            @RequestParam(required = false) String sceneCompanyId,
                                                            @RequestParam(required = false) String startTime,
                                                            @RequestParam(required = false) String endTime) {
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();

        String electricId = energyConsumptionTypeService.getWaterId();
        Map<String, Object> result = new HashMap<>();
        result.put("remark", DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<SceneRoomEntity> roomEntityList;
        List<EnergyDataEntity> list = new ArrayList<>();
        if (StringUtils.isNotEmpty(sceneCompanyId)) {
            roomEntityList = sceneRoomService.list(new LambdaQueryWrapper<SceneRoomEntity>()
                    .eq(SceneRoomEntity::getSceneCompanyId, sceneCompanyId));
            // 公司要 关联2个以上的空间才为特殊空间
            if (roomEntityList.size() >= 2) {
                list = Joins.of(EnergyDataEntity.class)
                        .selectAs(builder -> {
                            builder.add("scene_room_id", "sceneRoomId", false);
                            builder.add("SUM(meter_Value)", "meterValue", false);
                        })
                        .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                        .eq(EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                        .eq(EnergyDataEntity::getEnergyTypeId, electricId)
                        .isNotNull(EnergyDataEntity::getSceneRoomId)
                        .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                        .le(EnergyDataEntity::getSolidifyDate, end)
                        .groupBy(EnergyDataEntity::getSceneRoomId).joinList(EnergyDataEntity.class);
            }

        } else {
            roomEntityList = sceneRoomService.list(new LambdaQueryWrapper<SceneRoomEntity>()
                    .eq(StringUtils.isNotEmpty(sceneProjectId), SceneRoomEntity::getSceneProjectId, sceneProjectId));
            list = Joins.of(EnergyDataEntity.class)
                    .selectAs(builder -> {
                        builder.add("scene_room_id", "sceneRoomId", false);
                        builder.add("SUM(meter_Value)", "meterValue", false);
                    })
                    .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                    .eq(EnergyDataEntity::getEnergyTypeId, electricId)
                    .isNotNull(EnergyDataEntity::getSceneRoomId)
                    .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                    .le(EnergyDataEntity::getSolidifyDate, end)
                    .groupBy(EnergyDataEntity::getSceneRoomId).joinList(EnergyDataEntity.class);
        }

        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.stream().max(Comparator.comparing(EnergyDataEntity::getMeterValue)).orElse(null);
            EnergyDataEntity minData = list.stream().min(Comparator.comparing(EnergyDataEntity::getMeterValue)).orElse(null);
            Map<String, Object> map = new HashMap<>(2);
            map.put("name", roomEntityList.stream().filter(item -> StringUtils.equals(item.getId(), maxData.getSceneRoomId())).findFirst().get().getRoomName());
            map.put("value", maxData.getMeterValue().setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
            map = new HashMap<>(2);
            map.put("name", roomEntityList.stream().filter(item -> StringUtils.equals(item.getId(), minData.getSceneRoomId())).findFirst().get().getRoomName());
            map.put("value", maxData.getMeterValue().setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
            result.put("dataList", dataList);
        }
        return ResultResp.success(result);
    }


    /**
     * 时间用冷分析
     */
    @ApiOperation("时间用冷分析")
    @GetMapping("timeColdStatics")
    public ResultResp<Map<String, Object>> timeColdStatics(@RequestParam(required = false) String sceneProjectId,
                                                           @RequestParam(required = false) String sceneCompanyId,
                                                           @RequestParam(required = false) String startTime,
                                                           @RequestParam(required = false) String endTime) {
        String coldId = energyConsumptionTypeService.getColdId();
        List<Map<String, Object>> dataList = new ArrayList<>();
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();
        Map<String, List<EnergyDataEntity>> list = Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> {
                    builder.add("solidify_date", "solidifyDate", false);
                    builder.add("SUM(meter_Value)", "meterValue", false);
                })
                .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                .eq(EnergyDataEntity::getEnergyTypeId, coldId)
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .groupBy(EnergyDataEntity::getSolidifyDate).joinList(EnergyDataEntity.class)
                .stream()
                .collect(Collectors.groupingBy(energyData -> DateUtil.format(energyData.getSolidifyDate(), "yyyy-MM-dd"),
                        LinkedHashMap::new, Collectors.toList()));
        for (Map.Entry<String, List<EnergyDataEntity>> entry : list.entrySet()) {
            String date = entry.getKey();
            BigDecimal value = entry.getValue().stream().map(EnergyDataEntity::getMeterValue).reduce(BigDecimal.ZERO, BigDecimal::add);
            Map<String, Object> map = new HashMap<>(2);
            map.put("date", date);
            map.put("value", value.setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
        }
        Map<String, Object> result = new HashMap<>(2);
        result.put("remark", DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        result.put("dataList", dataList);
        return ResultResp.success(result);
    }


    /**
     * 空间用冷分析
     */
    @ApiOperation("空间用冷分析(返回的dataList数组，长度为2的情况下，第一条是最大值统计，第二条为最小值统计)")
    @GetMapping("roomColdStatics")
    public ResultResp<Map<String, Object>> roomColdStatics(@RequestParam(required = false) String sceneProjectId,
                                                           @RequestParam(required = false) String sceneCompanyId,
                                                           @RequestParam(required = false) String startTime,
                                                           @RequestParam(required = false) String endTime) {
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();

        String coldId = energyConsumptionTypeService.getColdId();
        Map<String, Object> result = new HashMap<>();
        result.put("remark", DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<SceneRoomEntity> roomEntityList;
        List<EnergyDataEntity> list = new ArrayList<>();
        if (StringUtils.isNotEmpty(sceneCompanyId)) {
            roomEntityList = sceneRoomService.list(new LambdaQueryWrapper<SceneRoomEntity>()
                    .eq(SceneRoomEntity::getSceneCompanyId, sceneCompanyId));
            // 公司要 关联2个以上的空间才为特殊空间
            if (roomEntityList.size() >= 2) {
                list = Joins.of(EnergyDataEntity.class)
                        .selectAs(builder -> {
                            builder.add("scene_room_id", "sceneRoomId", false);
                            builder.add("SUM(meter_Value)", "meterValue", false);
                        })
                        .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                        .eq(EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                        .eq(EnergyDataEntity::getEnergyTypeId, coldId)
                        .isNotNull(EnergyDataEntity::getSceneRoomId)
                        .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                        .le(EnergyDataEntity::getSolidifyDate, end)
                        .groupBy(EnergyDataEntity::getSceneRoomId).joinList(EnergyDataEntity.class);
            }

        } else {
            roomEntityList = sceneRoomService.list(new LambdaQueryWrapper<SceneRoomEntity>()
                    .eq(StringUtils.isNotEmpty(sceneProjectId), SceneRoomEntity::getSceneProjectId, sceneProjectId));
            list = Joins.of(EnergyDataEntity.class)
                    .selectAs(builder -> {
                        builder.add("scene_room_id", "sceneRoomId", false);
                        builder.add("SUM(meter_Value)", "meterValue", false);
                    })
                    .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                    .eq(EnergyDataEntity::getEnergyTypeId, coldId)
                    .isNotNull(EnergyDataEntity::getSceneRoomId)
                    .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                    .le(EnergyDataEntity::getSolidifyDate, end)
                    .groupBy(EnergyDataEntity::getSceneRoomId).joinList(EnergyDataEntity.class);
        }

        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.stream().max(Comparator.comparing(EnergyDataEntity::getMeterValue)).orElse(null);
            EnergyDataEntity minData = list.stream().min(Comparator.comparing(EnergyDataEntity::getMeterValue)).orElse(null);
            Map<String, Object> map = new HashMap<>(2);
            map.put("name", roomEntityList.stream().filter(item -> StringUtils.equals(item.getId(), maxData.getSceneRoomId())).findFirst().get().getRoomName());
            map.put("value", maxData.getMeterValue().setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
            map = new HashMap<>(2);
            map.put("name", roomEntityList.stream().filter(item -> StringUtils.equals(item.getId(), minData.getSceneRoomId())).findFirst().get().getRoomName());
            map.put("value", maxData.getMeterValue().setScale(2, RoundingMode.HALF_DOWN));
            dataList.add(map);
            result.put("dataList", dataList);
        }
        return ResultResp.success(result);
    }


    /**
     * 光伏
     */
    @ApiOperation("光伏")
    @GetMapping("photovoltaicPower")
    public ResultResp<PersonalizedEnergyPowerResp> photovoltaicPower(@RequestParam String sceneProjectId,
                                                                     @RequestParam(required = false) String sceneCompanyId,
                                                                     @RequestParam(required = false) String startTime,
                                                                     @RequestParam(required = false) String endTime) {
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();
        PersonalizedEnergyPowerResp powerResp = new PersonalizedEnergyPowerResp();
        powerResp.setRemark(DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);

        List<ProductTypeEntity> productTypes = productTypeService.getPhotovoltaic();
        List<String> modelIds = new ArrayList<>();
        for (ProductTypeEntity productTypeEntity : productTypes) {
            String modelIdStr = productTypeEntity.getModelIds();
            if (StringUtils.isNotEmpty(modelIdStr)) {
                modelIds.addAll(Arrays.asList(modelIdStr.split(",")));
            }
        }
        String[] modelIdsArray = modelIds.stream().distinct().toArray(String[]::new);
        powerResp.setCapacity(computeCapacity(modelIdsArray, start, end));
        powerResp.setStrand(computeStrand(modelIdsArray, start, end));
        powerResp.setTotalPower(computeTotalPower(sceneProjectId, sceneCompanyId, start, end));

        setPowerValues(powerResp, sceneProjectId, sceneCompanyId, start, end);
        return ResultResp.success(powerResp);
    }

    private void setPowerValues(PersonalizedEnergyPowerResp powerResp, String sceneProjectId, String sceneCompanyId,
                                LocalDateTime start, LocalDateTime end) {
        List<EnergyDataEntity> list = energyDataService.query()
                .select("DATE_FORMAT(solidify_date,'%Y-%m-%d') as solidifyDate", "SUM(meter_value) as meterValue")
                .eq(StringUtils.isNotEmpty(sceneProjectId), "scene_project_id", sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), "scene_company_id", sceneCompanyId)
                .eq("read_meter_type", IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType)
                .eq("statics_type", MeterDeviceStaticsTypeEnums.POWER_GENERATION.getValue())
                .ge(Objects.nonNull(start), "solidify_date", start)
                .le(Objects.nonNull(end), "solidify_date", end)
                .groupBy("DATE_FORMAT(solidify_date,'%Y-%m-%d')")
                .orderByDesc("solidify_date").list();
        BigDecimal maxPowerValue = BigDecimal.ZERO;
        BigDecimal minPowerValue = BigDecimal.ZERO;
        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.get(0);
            EnergyDataEntity minData = list.get(list.size() - 1);
            powerResp.setMaxPowerTime(maxData.getSolidifyDate());
            maxPowerValue = maxData.getMeterValue();
            powerResp.setMinPowerTime(minData.getSolidifyDate());
            minPowerValue = minData.getMeterValue();
        }
        powerResp.setMaxPowerValue(maxPowerValue);
        powerResp.setMinPowerValue(minPowerValue);

        list = energyDataService.query()
                .select("meter_device_id", "SUM(meter_value) as meterValue")
                .eq(StringUtils.isNotEmpty(sceneProjectId), "scene_project_id", sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), "scene_company_id", sceneCompanyId)
                .eq("read_meter_type", IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType)
                .eq("statics_type", MeterDeviceStaticsTypeEnums.POWER_GENERATION.getValue())
                .ge(Objects.nonNull(start), "solidify_date", start)
                .le(Objects.nonNull(end), "solidify_date", end)
                .groupBy("meter_device_id")
                .orderByDesc("SUM(meter_value)").list();
        BigDecimal deviceMaxPowerValue = BigDecimal.ZERO;
        BigDecimal deviceMinPowerValue = BigDecimal.ZERO;
        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.get(0);
            EnergyDataEntity minData = list.get(list.size() - 1);
            MeterDeviceEntity maxMeterDevice = meterDeviceService.getById(maxData.getMeterDeviceId());
            MeterDeviceEntity minMeterDevice = meterDeviceService.getById(minData.getMeterDeviceId());
            powerResp.setDeviceMaxPowerName(Objects.isNull(maxMeterDevice) ? null : maxMeterDevice.getDeviceName());
            deviceMaxPowerValue = maxData.getMeterValue();
            powerResp.setDeviceMinPowerName(Objects.isNull(minMeterDevice) ? null : minMeterDevice.getDeviceName());
            deviceMinPowerValue = minData.getMeterValue();
        }
        powerResp.setDeviceMaxPowerValue(deviceMaxPowerValue.setScale(2, RoundingMode.HALF_DOWN));
        powerResp.setDeviceMinPowerValue(deviceMinPowerValue.setScale(2, RoundingMode.HALF_DOWN));
    }

    /**
     * 后台管理-数据管理-能源数据-计量值 （此处计量为读表类型为“光伏电表”并且统计类型为“发电量”的计量值）
     */
    private BigDecimal computeTotalPower(String sceneProjectId, String sceneCompanyId, LocalDateTime start, LocalDateTime end) {
        BigDecimal value = Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> builder.add("SUM(meter_value)", "meterValue", false))
                .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType)
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.POWER_GENERATION.getValue())
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(Objects.nonNull(end), EnergyDataEntity::getSolidifyDate, end)
                .joinGetOne(BigDecimal.class);
        return ObjectUtils.defaultIfNull(value, BigDecimal.ZERO).setScale(2, RoundingMode.HALF_DOWN);

    }

    private Integer computeStrand(String[] modelIdsArray, LocalDateTime start, LocalDateTime end) {
        return physicalModelService.queryValueByIdsAndName(modelIdsArray, "组串", start, end).intValue();
    }

    /**
     * 计算光伏装机容量
     */
    private BigDecimal computeCapacity(String[] modelIdsArray, LocalDateTime start, LocalDateTime end) {
        return physicalModelService.queryValueByIdsAndName(modelIdsArray, "光伏装机容量", start, end);
    }

    /**
     * 储能
     */
    @ApiOperation("储能")
    @GetMapping("energystorage")
    public ResultResp<PersonalizedEnergyStorageResp> energyStorage(@RequestParam String sceneProjectId,
                                                                   @RequestParam(required = false) String sceneCompanyId,
                                                                   @RequestParam(required = false) String startTime,
                                                                   @RequestParam(required = false) String endTime) {
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();
        PersonalizedEnergyStorageResp powerResp = new PersonalizedEnergyStorageResp();
        powerResp.setRemark(DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);
        powerResp.setEnergyStorage(computeEnergyStorage(sceneProjectId, sceneCompanyId));

        List<ProductTypeEntity> productTypes = productTypeService.getEnergyStorage();
        List<String> modelIds = new ArrayList<>();
        for (ProductTypeEntity productTypeEntity : productTypes) {
            String modelIdStr = productTypeEntity.getModelIds();
            if (StringUtils.isNotEmpty(modelIdStr)) {
                modelIds.addAll(Arrays.asList(modelIdStr.split(",")));
            }
        }
        powerResp.setCapacity(computeEnergyCapacity(modelIds.stream().distinct().toArray(String[]::new), start, end));
        setEnergyStorageValues(powerResp, sceneProjectId, sceneCompanyId, start, end);
        return ResultResp.success(powerResp);
    }

    private void setEnergyStorageValues(PersonalizedEnergyStorageResp powerResp, String sceneProjectId, String sceneCompanyId,
                                        LocalDateTime start, LocalDateTime end) {
        List<EnergyDataEntity> list = energyDataService.query()
                .select("DATE_FORMAT(solidify_date,'%Y-%m-%d') as solidifyDate", "SUM(meter_value) as meterValue")
                .eq(StringUtils.isNotEmpty(sceneProjectId), "scene_project_id", sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), "scene_company_id", sceneCompanyId)
                .eq("read_meter_type", IMeterDeviceEnums.ReadMeterType.readMeterType12.readMeterType)
                .eq("statics_type", MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_CHARGING.getValue())
                .ge(Objects.nonNull(start), "solidify_date", start)
                .le(Objects.nonNull(end), "solidify_date", end)
                .groupBy("DATE_FORMAT(solidify_date,'%Y-%m-%d')")
                .orderByDesc("solidify_date").list();
        BigDecimal maxChargingValue = BigDecimal.ZERO;
        BigDecimal minChargingValue = BigDecimal.ZERO;
        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.get(0);
            EnergyDataEntity minData = list.get(list.size() - 1);
            powerResp.setMaxChargingTime(maxData.getSolidifyDate());
            powerResp.setMinChargingTime(minData.getSolidifyDate());
            maxChargingValue = maxData.getMeterValue();
            minChargingValue = minData.getMeterValue();
        }
        powerResp.setMaxChargingValue(maxChargingValue.setScale(2, RoundingMode.HALF_DOWN));
        powerResp.setMinChargeValue(minChargingValue.setScale(2, RoundingMode.HALF_DOWN));

        list = energyDataService.query()
                .select("DATE_FORMAT(solidify_date,'%Y-%m-%d') as solidifyDate", "SUM(meter_value) as meterValue")
                .eq(StringUtils.isNotEmpty(sceneProjectId), "scene_project_id", sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), "scene_company_id", sceneCompanyId)
                .eq("read_meter_type", IMeterDeviceEnums.ReadMeterType.readMeterType11.readMeterType)
                .eq("statics_type", MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_DISCHARGE.getValue())
                .ge(Objects.nonNull(start), "solidify_date", start)
                .le(Objects.nonNull(end), "solidify_date", end)
                .groupBy("DATE_FORMAT(solidify_date,'%Y-%m-%d')")
                .orderByDesc("solidify_date").list();
        BigDecimal maxDischargeValue = BigDecimal.ZERO;
        BigDecimal minDischargeValue = BigDecimal.ZERO;
        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.get(0);
            EnergyDataEntity minData = list.get(list.size() - 1);
            powerResp.setMaxDischargeDate(maxData.getSolidifyDate());
            maxDischargeValue = maxData.getMeterValue();
            minDischargeValue = minData.getMeterValue();
            powerResp.setMinDischargeDate(minData.getSolidifyDate());
        }
        powerResp.setMaxDischargeValue(maxDischargeValue.setScale(2, RoundingMode.HALF_DOWN));
        powerResp.setMinDischargeValue(minDischargeValue.setScale(2, RoundingMode.HALF_DOWN));
    }

    /**
     * 储能容量
     */
    private BigDecimal computeEnergyCapacity(String[] modelIdsArray, LocalDateTime start, LocalDateTime end) {
        return physicalModelService.queryValueByIdsAndName(modelIdsArray, "储能容量", start, end);
    }

    /**
     * 储能利用率
     */
    private BigDecimal computeEnergyStorage(String sceneProjectId, String sceneCompanyId) {
        // 储能设备年累计充电量
        LocalDateTime start1 = LocalDate.now().with(TemporalAdjusters.firstDayOfYear()).atTime(LocalTime.MIN);
        LocalDateTime end1 = LocalDate.now().with(TemporalAdjusters.lastDayOfYear()).atTime(LocalTime.MAX);
        BigDecimal yearMeterValue = ObjectUtil.defaultIfNull(Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> builder.add("SUM(meter_value)", "meterValue", false))
                .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType12.getValue())
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_CHARGING.getValue())
                .ge(EnergyDataEntity::getSolidifyDate, start1)
                .le(EnergyDataEntity::getSolidifyDate, end1)
                .joinGetOne(BigDecimal.class), BigDecimal.ZERO);
        // 储能额定容量: TODO: 管理后台-设备列表-运行状态-额定容量（ 对应上方筛选设备的装机容量）
        BigDecimal ratedCapacity = BigDecimal.ONE;
        // 储能利用率=储能设备年累计充电量/（储能额定容量*365）*100%
        BigDecimal val = ratedCapacity
                .multiply(new BigDecimal("365")).multiply(new BigDecimal("100"));
        return ratedCapacity.doubleValue() == 0.0D ? BigDecimal.ZERO : yearMeterValue.divide(val, 2, RoundingMode.HALF_DOWN);
    }

    /**
     * 充电桩
     */
    @ApiOperation("充电桩")
    @GetMapping("chargingstation")
    public ResultResp<PersonalizedEnergyChargingStationResp> chargingStation(@RequestParam String sceneProjectId,
                                                                             @RequestParam(required = false) String sceneCompanyId,
                                                                             @RequestParam(required = false) String startTime,
                                                                             @RequestParam(required = false) String endTime) {
        LocalDateTime start = StringUtils.isNotEmpty(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.isNotEmpty(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();

        PersonalizedEnergyChargingStationResp powerResp = new PersonalizedEnergyChargingStationResp();
        powerResp.setRemark(DEFAULT_REMARKS[(int) (Math.random() * DEFAULT_REMARKS.length)]);

        List<ProductTypeEntity> chargingStations = productTypeService.getChargingStation();
        powerResp.setNum(getMeterDeviceNum(sceneProjectId, chargingStations.stream().map(ProductTypeEntity::getId).collect(Collectors.toSet())));
        powerResp.setTotalChargingPower(queryTotalChargingPower(sceneProjectId, sceneCompanyId, start, end));
        powerResp.setTotalDischargePower(queryTotalDisChargingPower(sceneProjectId, sceneCompanyId, start, end));
        setEnergyChargingStationValues(powerResp, sceneProjectId, sceneCompanyId, start, end);
        return ResultResp.success(powerResp);
    }

    private BigDecimal queryTotalDisChargingPower(String sceneProjectId, String sceneCompanyId, LocalDateTime start, LocalDateTime end) {
        BigDecimal value = Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> builder.add("SUM(meter_Value)", "meterValue", false))
                .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType41.getValue())
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_DISCHARGE.getValue())
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end).joinGetOne(BigDecimal.class);
        return ObjectUtils.defaultIfNull(value, BigDecimal.ZERO).setScale(2, RoundingMode.HALF_DOWN);
    }

    private void setEnergyChargingStationValues(PersonalizedEnergyChargingStationResp chargingStationResp,
                                                String sceneProjectId, String sceneCompanyId,
                                                LocalDateTime start, LocalDateTime end) {
        List<EnergyDataEntity> list = energyDataService.query()
                .select("DATE_FORMAT(solidify_date,'%Y-%m-%d') as solidifyDate", "SUM(meter_value) as meterValue")
                .eq(StringUtils.isNotEmpty(sceneProjectId), "scene_project_id", sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), "scene_company_id", sceneCompanyId)
                .eq("read_meter_type", IMeterDeviceEnums.ReadMeterType.readMeterType41.readMeterType)
                .eq("statics_type", MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_CHARGING.getValue())
                .ge(Objects.nonNull(start), "solidify_date", start)
                .le(Objects.nonNull(end), "solidify_date", end)
                .groupBy("DATE_FORMAT(solidify_date,'%Y-%m-%d')")
                .orderByDesc("solidify_date").list();
        BigDecimal maxChargingValue = BigDecimal.ZERO;
        BigDecimal minChargingValue = BigDecimal.ZERO;
        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.get(0);
            EnergyDataEntity minData = list.get(list.size() - 1);
            chargingStationResp.setMaxChargingTime(maxData.getSolidifyDate());
            maxChargingValue = maxData.getMeterValue();
            minChargingValue = minData.getMeterValue();
            chargingStationResp.setMinChargingTime(minData.getSolidifyDate());
        }
        chargingStationResp.setMaxChargingValue(maxChargingValue.setScale(2, RoundingMode.HALF_DOWN));
        chargingStationResp.setMinChargeValue(minChargingValue.setScale(2, RoundingMode.HALF_DOWN));

        BigDecimal maxDisChargingValue = BigDecimal.ZERO;
        BigDecimal minDisChargingValue = BigDecimal.ZERO;
        list = energyDataService.query()
                .select("DATE_FORMAT(solidify_date,'%Y-%m-%d') as solidifyDate", "SUM(meter_value) as meterValue")
                .eq(StringUtils.isNotEmpty(sceneProjectId), "scene_project_id", sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), "scene_company_id", sceneCompanyId)
                .eq("read_meter_type", IMeterDeviceEnums.ReadMeterType.readMeterType41.readMeterType)
                .eq("statics_type", MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_DISCHARGE.getValue())
                .ge(Objects.nonNull(start), "solidify_date", start)
                .le(Objects.nonNull(end), "solidify_date", end)
                .groupBy("DATE_FORMAT(solidify_date,'%Y-%m-%d')")
                .orderByDesc("solidify_date").list();
        if (!list.isEmpty()) {
            EnergyDataEntity maxData = list.get(0);
            EnergyDataEntity minData = list.get(list.size() - 1);
            maxDisChargingValue = maxData.getMeterValue();
            minDisChargingValue = minData.getMeterValue();
            chargingStationResp.setMaxDischargeDate(maxData.getSolidifyDate());
            chargingStationResp.setMinDischargeDate(minData.getSolidifyDate());
        }
        chargingStationResp.setMaxDischargeValue(maxDisChargingValue.setScale(2, RoundingMode.HALF_DOWN));
        chargingStationResp.setMinDischargeValue(minDisChargingValue.setScale(2, RoundingMode.HALF_DOWN));

    }

    /**
     * 充电桩总充电量：管理后台-数据管理-能源数据-计量值。（此处计量为读表类型为“充电桩电表 ”并且统计类型为“充电量”的计量值）
     */
    private BigDecimal queryTotalChargingPower(String sceneProjectId, String sceneCompanyId, LocalDateTime start, LocalDateTime end) {
        BigDecimal value = Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> builder.add("SUM(meter_Value)", "meterValue", false))
                .eq(StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(StringUtils.isNotEmpty(sceneCompanyId), EnergyDataEntity::getSceneCompanyId, sceneCompanyId)
                .eq(EnergyDataEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.readMeterType41.getValue())
                .eq(EnergyDataEntity::getStaticsType, MeterDeviceStaticsTypeEnums.ENERGY_STORAGE_CHARGING.getValue())
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end).joinGetOne(BigDecimal.class);
        return ObjectUtils.defaultIfNull(value, BigDecimal.ZERO).setScale(2, RoundingMode.HALF_DOWN);
    }

    private int getMeterDeviceNum(String sceneProjectId, Set<String> productTypeIds) {
        return (int) meterDeviceService.count(new LambdaQueryWrapper<MeterDeviceEntity>()
                .eq(StringUtils.isNotEmpty(sceneProjectId), MeterDeviceEntity::getSceneProjectId, sceneProjectId)
                .in(MeterDeviceEntity::getProductTypeId, productTypeIds)
                .eq(MeterDeviceEntity::getDeviceStatus, IMeterDeviceEnums.DeviceStatus.deviceStatus1.getValue())
        );
    }
}